/*
 * Copyright (C), 2002-2017, 南京苏宁软件技术有限公司
 * FileName: AreaTaskServiceImpl.java
 * Author:   10070706
 * Date:     2017年1月10日 上午11:23:28
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.sawp.service.impl.mainpushnew;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import com.suning.sawp.constants.MainPushConstants;
import com.suning.sawp.dto.common.QueryResult;
import com.suning.sawp.exception.SawpException;
import com.suning.sawp.intf.dao.mainpushnew.AreaTaskDao;
import com.suning.sawp.intf.mainpushnew.AreaTaskService;
import com.suning.sawp.intf.mainpushnew.DistributeStatusService;
import com.suning.sawp.intf.mainpushnew.RedPointTipsService;
import com.suning.sawp.po.mainpushnew.AreaModelRel;
import com.suning.sawp.po.mainpushnew.AreaTask;
import com.suning.sawp.po.mainpushnew.RedPointTips;
import com.suning.sawp.po.mainpushnew.StoreTask;
import com.suning.sawp.service.util.BigDecimalUtils;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.MainPushExcelHandle;
import com.suning.sawp.vo.mainpushnew.AreaTaskDetailVo;
import com.suning.sawp.vo.mainpushnew.AreaTaskModelCompleteVo;
import com.suning.sawp.vo.mainpushnew.AreaTaskModelDetailVo;
import com.suning.sawp.vo.mainpushnew.AreaTaskSaleInfoVo;
import com.suning.sawp.vo.mainpushnew.AreaTaskStoreDetailVo;
import com.suning.sawp.vo.mainpushnew.AreaTaskTargetExportVo;
import com.suning.sawp.vo.mainpushnew.AreaTaskVo;
import com.suning.sawp.vo.mainpushnew.CalStoreTaskDistributeVo;
import com.suning.sawp.vo.mainpushnew.StoreInfoVo;
import com.suning.sawp.vo.mainpushnew.StoreTaskTotalAmountVo;
import com.suning.sawp.vo.mainpushnew.StoreTaskTypeActualVo;
import com.suning.sawp.vo.mainpushnew.StoreTaskTypeTargetVo;

/**
 * 功能简述: 大区任务service实现类<br>
 *
 * @author 10070706 陈辉
 */
@Service("areaTaskService")
public class AreaTaskServiceImpl implements AreaTaskService {

    private static final Logger LOG = LoggerFactory.getLogger(AreaTaskServiceImpl.class);

    @Autowired
    private DistributeStatusService distributeStatusService;

    @Autowired
    private RedPointTipsService redPointTipsService;

    /**
     * 大区导出任务的指标
     */
    private static List<String> areaTaskCompleteIndicator;

    static {
        areaTaskCompleteIndicator = new ArrayList<String>();
        areaTaskCompleteIndicator.add("门店编码");
        areaTaskCompleteIndicator.add("门店名称");
        areaTaskCompleteIndicator.add("综合");
        areaTaskCompleteIndicator.add("A类");
        areaTaskCompleteIndicator.add("B类");
        areaTaskCompleteIndicator.add("目标综合");
        areaTaskCompleteIndicator.add("实际综合");
        areaTaskCompleteIndicator.add("A类目标");
        areaTaskCompleteIndicator.add("A类实际");
        areaTaskCompleteIndicator.add("B类目标");
        areaTaskCompleteIndicator.add("B类实际");
        areaTaskCompleteIndicator.add("综合");
        areaTaskCompleteIndicator.add("A类");
        areaTaskCompleteIndicator.add("B类");
        areaTaskCompleteIndicator.add("B2类");
        areaTaskCompleteIndicator.add("实际占比");
    }

    @Autowired
    private AreaTaskDao areaTaskDao;

    @Resource(name = "areaTaskService")
    private AreaTaskService self;

    @Override
    public String query5DisCodeByUserId(String userId) {
        return areaTaskDao.query5DisCodeByUserId(userId);
    }

    @Override
    public QueryResult<AreaTaskVo> queryAreaTaskInfo(String disCode, String taskTopic, String month, Integer pageNo,
            Integer pageLimit) {
        Integer pageSize = checkPageLimit(pageLimit);
        Integer startRow = (pageNo - 1) * pageSize;
        List<AreaTaskVo> areaTaskList = areaTaskDao.queryAreaTaskInfo(disCode, taskTopic, month, startRow, pageLimit);
        int currentMonth = Integer.parseInt(DateUtils.getThisMonth());
        int taskMonth = 0;
        for (AreaTaskVo task : areaTaskList) {
            taskMonth = StringUtils.isEmpty(task.getMonth()) ? 0 : Integer.parseInt(task.getMonth());
            if (taskMonth < currentMonth) {
                task.setIsCurrent(MainPushConstants.SAMLL_THAN_CURRENT_MONTH);
            } else if (taskMonth > currentMonth) {
                task.setIsCurrent(MainPushConstants.BIG_THAN_CURRENT_MONTH);
            } else {
                task.setIsCurrent(MainPushConstants.EQUAL_THAN_CURRENT_MONTH);
            }
        }

        Integer totalSize = areaTaskDao.queryAreaTaskInfoSize(disCode, taskTopic, month, startRow, pageLimit);
        QueryResult<AreaTaskVo> result = new QueryResult<AreaTaskVo>();
        result.setRecords(areaTaskList);
        result.setTotalSize(totalSize);
        return result;
    }

    @Override
    public XSSFWorkbook queryAreaSaleTaskCondition(Long... areaTaskIds) {
        Map<String, List<AreaTaskSaleInfoVo>> map = new HashMap<String, List<AreaTaskSaleInfoVo>>();

        AreaTask areaTask = null;
        for (Long areaTaskId : areaTaskIds) {
            areaTask = areaTaskDao.queryAreaTaskByAreaTaskId(areaTaskId);

            List<AreaTaskSaleInfoVo> areaTaskSaleInfo = null;
            List<StoreTaskTypeTargetVo> targetList = areaTaskDao.queryStoreTaskTargetInfo(areaTaskId);
            if (!CollectionUtils.isEmpty(targetList)) {
                List<StoreTaskTypeActualVo> actualList = areaTaskDao
                        .queryStoreTaskActualSaleInfo(areaTask.getHqTaskId(), areaTask.getDisCode());
                List<StoreTaskTotalAmountVo> totalList = areaTaskDao.queryTotalAmountOfCate(areaTask.getDisCode(),
                        areaTask.getCateCode(), areaTask.getMonth());

                areaTaskSaleInfo = buildAreaTaskSaleInfo(targetList, actualList, totalList);
            }
            map.put(areaTask.getTaskTopic(), areaTaskSaleInfo);

        }

        // 写excel
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);

        for (Map.Entry<String, List<AreaTaskSaleInfoVo>> entry : map.entrySet()) {
            XSSFSheet sheet = wb.createSheet(entry.getKey());

            // 第一行
            XSSFRow row = sheet.createRow(0);

            if (CollectionUtils.isEmpty(entry.getValue())) {
                row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue("暂未分配\"" + entry.getKey() + "\"至各个门店，请先分配!");
                continue;
            }

            XSSFCell cell = row.createCell(0, Cell.CELL_TYPE_STRING);
            cell.setCellValue("门店");
            cell.setCellStyle(style);
            CellRangeAddress region = new CellRangeAddress(0, 0, 0, 1);
            sheet.addMergedRegion(region);

            cell = row.createCell(2, Cell.CELL_TYPE_STRING);
            cell.setCellValue("完成率");
            cell.setCellStyle(style);
            region = new CellRangeAddress(0, 0, 2, 4);
            sheet.addMergedRegion(region);

            cell = row.createCell(5, Cell.CELL_TYPE_STRING);
            cell.setCellValue("台数");
            cell.setCellStyle(style);
            region = new CellRangeAddress(0, 0, 5, 10);
            sheet.addMergedRegion(region);

            cell = row.createCell(11, Cell.CELL_TYPE_STRING);
            cell.setCellValue("销售额");
            cell.setCellStyle(style);
            region = new CellRangeAddress(0, 0, 11, 14);
            sheet.addMergedRegion(region);

            cell = row.createCell(15, Cell.CELL_TYPE_STRING);
            cell.setCellValue("销售额占比");
            cell.setCellStyle(style);

            // 第二行
            row = sheet.createRow(1);
            for (int j = 0; j < areaTaskCompleteIndicator.size(); j++) {
                cell = row.createCell(j, Cell.CELL_TYPE_STRING);
                cell.setCellValue(areaTaskCompleteIndicator.get(j));
                cell.setCellStyle(style);
            }

            // 第三行
            List<AreaTaskSaleInfoVo> list = entry.getValue();
            AreaTaskSaleInfoVo summation = getSummationAreaTaskSaleInfoVo(list);
            list.remove(summation);
            row = sheet.createRow(2);
            cell = row.createCell(0, Cell.CELL_TYPE_STRING);
            cell.setCellValue("总计");
            cell.setCellStyle(style);
            region = new CellRangeAddress(2, 2, 0, 1);
            sheet.addMergedRegion(region);
            if (null != summation) {
                row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(summation.getSaleNumCompleteRate());
                row.createCell(3, Cell.CELL_TYPE_STRING).setCellValue(summation.getTypeACompleteRate());
                row.createCell(4, Cell.CELL_TYPE_STRING).setCellValue(summation.getTypeBCompleteRate());
                row.createCell(5, Cell.CELL_TYPE_STRING).setCellValue(summation.getTotalTargetNum());
                row.createCell(6, Cell.CELL_TYPE_STRING).setCellValue(summation.getTotalActualNum());
                row.createCell(7, Cell.CELL_TYPE_STRING).setCellValue(summation.getTypeATargetNum());
                row.createCell(8, Cell.CELL_TYPE_STRING).setCellValue(summation.getTypeAActualNum());
                row.createCell(9, Cell.CELL_TYPE_STRING).setCellValue(summation.getTypeBTargetNum());
                row.createCell(10, Cell.CELL_TYPE_STRING).setCellValue(summation.getTypeBActualNum());
                row.createCell(11, Cell.CELL_TYPE_STRING).setCellValue(String.valueOf(summation.getTotalSaleAmount()));
                row.createCell(12, Cell.CELL_TYPE_STRING).setCellValue(String.valueOf(summation.getTypeASaleAmount()));
                row.createCell(13, Cell.CELL_TYPE_STRING).setCellValue(String.valueOf(summation.getTypeBSaleAmount()));
                row.createCell(14, Cell.CELL_TYPE_STRING).setCellValue(String.valueOf(summation.getTypeB2SaleAmount()));
                row.createCell(15, Cell.CELL_TYPE_STRING).setCellValue(summation.getSaleAmountActualRate());
            }

            // 第四行及其他

            for (int j = 0; j < list.size(); j++) {
                row = sheet.createRow(3 + j);
                row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getStoreCode());
                row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getStoreName());
                row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getSaleNumCompleteRate());
                row.createCell(3, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getTypeACompleteRate());
                row.createCell(4, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getTypeBCompleteRate());
                row.createCell(5, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getTotalTargetNum());
                row.createCell(6, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getTotalActualNum());
                row.createCell(7, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getTypeATargetNum());
                row.createCell(8, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getTypeAActualNum());
                row.createCell(9, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getTypeBTargetNum());
                row.createCell(10, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getTypeBActualNum());
                row.createCell(11, Cell.CELL_TYPE_STRING)
                        .setCellValue(String.valueOf(list.get(j).getTotalSaleAmount()));
                row.createCell(12, Cell.CELL_TYPE_STRING)
                        .setCellValue(String.valueOf(list.get(j).getTypeASaleAmount()));
                row.createCell(13, Cell.CELL_TYPE_STRING)
                        .setCellValue(String.valueOf(list.get(j).getTypeBSaleAmount()));
                row.createCell(14, Cell.CELL_TYPE_STRING)
                        .setCellValue(String.valueOf(list.get(j).getTypeB2SaleAmount()));
                row.createCell(15, Cell.CELL_TYPE_STRING).setCellValue(list.get(j).getSaleAmountActualRate());
            }
        }
        return wb;
    }

    /**
     * 
     * 功能描述: 从大区导出情况中取出合计的那一列<br>
     * 
     * @param list
     * @return
     */
    private AreaTaskSaleInfoVo getSummationAreaTaskSaleInfoVo(List<AreaTaskSaleInfoVo> list) {
        for (AreaTaskSaleInfoVo per : list) {
            if (StringUtils.equals("-1", per.getStoreCode())) {
                return per;
            }
        }
        return null;
    }

    /**
     * 
     * 功能描述: 以分配门店为准，没分配的门店，不展示<br>
     *
     * @param targetList
     * @param actualList
     * @param totalList
     * @return
     */
    private List<AreaTaskSaleInfoVo> buildAreaTaskSaleInfo(List<StoreTaskTypeTargetVo> targetList,
            List<StoreTaskTypeActualVo> actualList, List<StoreTaskTotalAmountVo> totalList) {

        Map<String, AreaTaskSaleInfoVo> result = new HashMap<String, AreaTaskSaleInfoVo>();
        AreaTaskSaleInfoVo saleInfo = null;

        Integer totalTargetNum = null;
        Integer totalActualNum = null;
        BigDecimal totalActualAmount = null;

        StoreTaskTypeActualVo actual = null;
        StoreTaskTotalAmountVo total = null;

        for (StoreTaskTypeTargetVo per : targetList) {
            if (!result.containsKey(per.getStoreCode())) {
                saleInfo = new AreaTaskSaleInfoVo();
                saleInfo.setStoreCode(per.getStoreCode());
                saleInfo.setStoreName(per.getStoreName());
                result.put(per.getStoreCode(), saleInfo);
            } else {
                saleInfo = result.get(per.getStoreCode());
            }

            Integer actualNum = 0;
            BigDecimal actualAmount = new BigDecimal(0);
            BigDecimal totalAmount = new BigDecimal(0);

            actual = getActualByStoreAndType(actualList, per.getStoreCode(), per.getTaskType());
            if (null != actual) {
                actualNum = actual.getActualNum();
                if (null == actualNum) {
                    actualNum = 0;
                }
                actualAmount = actual.getActualAmount();
                if (null == actualAmount) {
                    actualAmount = new BigDecimal(0);
                }
            } else {
                actualNum = 0;
                actualAmount = new BigDecimal(0);
            }

            total = getTotalAmountByStore(totalList, per.getStoreCode());
            if (null != total) {
                totalAmount = total.getTotalAmount();
                if (null == totalAmount) {
                    totalAmount = new BigDecimal(0);
                }
            } else {
                totalAmount = new BigDecimal(0);
            }

            // B2不计算数量
            if (!StringUtils.equals("B2", per.getTaskType())) {
                // 目标综合
                if (null == saleInfo.getTotalTargetNum()) {
                    saleInfo.setTotalTargetNum(null == per.getTargetNum() ? Integer.valueOf(0) : per.getTargetNum());
                } else {
                    totalTargetNum = saleInfo.getTotalTargetNum()
                            + (null == per.getTargetNum() ? Integer.valueOf(0) : per.getTargetNum());
                    saleInfo.setTotalTargetNum(totalTargetNum);
                }

                // 实际综合
                if (null == saleInfo.getTotalActualNum()) {
                    saleInfo.setTotalActualNum(actualNum);
                } else {
                    totalActualNum = saleInfo.getTotalActualNum() + actualNum;
                    saleInfo.setTotalActualNum(totalActualNum);
                }
            }

            // A B B2都计算金额
            // 实际销售总额
            if (null == saleInfo.getTotalSaleAmount()) {
                saleInfo.setTotalSaleAmount(BigDecimalUtils.halfUpTwoDecimal(actualAmount));
            } else {
                totalActualAmount = saleInfo.getTotalSaleAmount().add(actualAmount);
                saleInfo.setTotalSaleAmount(BigDecimalUtils.halfUpTwoDecimal(totalActualAmount));
            }

            if (StringUtils.equals("A", per.getTaskType())) {
                saleInfo.setTypeATargetNum(null == per.getTargetNum() ? 0 : per.getTargetNum());
                saleInfo.setTypeAActualNum(actualNum);
                saleInfo.setTypeASaleAmount(actualAmount);
            } else if (StringUtils.equals("B", per.getTaskType())) {
                saleInfo.setTypeBTargetNum(null == per.getTargetNum() ? 0 : per.getTargetNum());
                saleInfo.setTypeBActualNum(actualNum);
                saleInfo.setTypeBSaleAmount(actualAmount);
            } else if (StringUtils.equals("B2", per.getTaskType())) {
                saleInfo.setTypeB2SaleAmount(actualAmount);
            }

            // 品类总销售额，用于计算销售额占比
            if (null == saleInfo.getTotalCateSaleAmount()) {
                saleInfo.setTotalCateSaleAmount(totalAmount);
            }
        }

        // Map转为list，同步处理其他依赖现有值而计算的值
        List<AreaTaskSaleInfoVo> list = new ArrayList<AreaTaskSaleInfoVo>();

        String typeANumRate = null;
        String typeBNumRate = null;
        String numRate = null;
        String actualAmountRate = null;

        // 所有门店的总计
        int totalTypeAActualNum = 0;
        int totalTypeBActualNum = 0;
        int totalTypeATargetNum = 0;
        int totalTypeBTargetNum = 0;
        BigDecimal totalTypeAAmount = new BigDecimal(0);
        BigDecimal totalTypeBAmount = new BigDecimal(0);
        BigDecimal totalTypeB2Amount = new BigDecimal(0);
        BigDecimal totalCateAmount = new BigDecimal(0);

        AreaTaskSaleInfoVo sale = null;
        for (Map.Entry<String, AreaTaskSaleInfoVo> entry : result.entrySet()) {
            sale = entry.getValue();

            // 存在某一个类别没有的情况，所以需要再次初始化
            if (null == sale.getTypeATargetNum()) {
                sale.setTypeATargetNum(0);
            }

            if (null == sale.getTypeAActualNum()) {
                sale.setTypeAActualNum(0);
            }

            if (null == sale.getTypeBTargetNum()) {
                sale.setTypeBTargetNum(0);
            }

            if (null == sale.getTypeBActualNum()) {
                sale.setTypeBActualNum(0);
            }

            if (null == sale.getTypeASaleAmount()) {
                sale.setTypeASaleAmount(new BigDecimal(0));
            }

            if (null == sale.getTypeBSaleAmount()) {
                sale.setTypeBSaleAmount(new BigDecimal(0));
            }

            if (null == sale.getTypeB2SaleAmount()) {
                sale.setTypeB2SaleAmount(new BigDecimal(0));
            }

            typeANumRate = BigDecimalUtils.calPercent(sale.getTypeAActualNum(), sale.getTypeATargetNum());
            typeBNumRate = BigDecimalUtils.calPercent(sale.getTypeBActualNum(), sale.getTypeBTargetNum());
            numRate = calTotalNumRate(
                    BigDecimalUtils.calRatioForThreeDecimal(sale.getTypeAActualNum(), sale.getTypeATargetNum()),
                    BigDecimalUtils.calRatioForThreeDecimal(sale.getTypeBActualNum(), sale.getTypeBTargetNum()));
            actualAmountRate = BigDecimalUtils.calPercent(sale.getTotalSaleAmount(), sale.getTotalCateSaleAmount());

            sale.setTypeACompleteRate(typeANumRate);
            sale.setTypeBCompleteRate(typeBNumRate);
            sale.setSaleNumCompleteRate(numRate);
            sale.setSaleAmountActualRate(actualAmountRate);

            list.add(sale);

            // A,B类数量合计
            totalTypeAActualNum += null == sale.getTypeAActualNum() ? 0 : sale.getTypeAActualNum();
            totalTypeBActualNum += null == sale.getTypeBActualNum() ? 0 : sale.getTypeBActualNum();
            totalTypeATargetNum += null == sale.getTypeATargetNum() ? 0 : sale.getTypeATargetNum();
            totalTypeBTargetNum += null == sale.getTypeBTargetNum() ? 0 : sale.getTypeBTargetNum();

            // A,B,B2类金额合计
            totalTypeAAmount = totalTypeAAmount
                    .add(null == sale.getTypeASaleAmount() ? new BigDecimal(0) : sale.getTypeASaleAmount());
            totalTypeBAmount = totalTypeBAmount
                    .add(null == sale.getTypeBSaleAmount() ? new BigDecimal(0) : sale.getTypeBSaleAmount());
            totalTypeB2Amount = totalTypeB2Amount
                    .add(null == sale.getTypeB2SaleAmount() ? new BigDecimal(0) : sale.getTypeB2SaleAmount());

            totalCateAmount = totalCateAmount
                    .add(null == sale.getTotalCateSaleAmount() ? new BigDecimal(0) : sale.getTotalCateSaleAmount());
        }

        BigDecimal totalStoreAmount = BigDecimalUtils
                .halfUpTwoDecimal(totalTypeAAmount.add(totalTypeBAmount).add(totalTypeB2Amount));
        String totalTypeANumRate = BigDecimalUtils.calPercent(totalTypeAActualNum, totalTypeATargetNum);
        String totalTypeBNumRate = BigDecimalUtils.calPercent(totalTypeBActualNum, totalTypeBTargetNum);
        String totalNumRate = calTotalNumRate(
                BigDecimalUtils.calRatioForThreeDecimal(totalTypeAActualNum, totalTypeATargetNum),
                BigDecimalUtils.calRatioForThreeDecimal(totalTypeBActualNum, totalTypeBTargetNum));
        String totalActualAmountRate = BigDecimalUtils.calPercent(totalStoreAmount, totalCateAmount);

        AreaTaskSaleInfoVo sum = new AreaTaskSaleInfoVo();

        // 合计
        sum.setStoreCode("-1");
        sum.setStoreName(StringUtils.EMPTY);
        sum.setTypeATargetNum(totalTypeATargetNum);
        sum.setTypeAActualNum(totalTypeAActualNum);
        sum.setTypeBTargetNum(totalTypeBTargetNum);
        sum.setTypeBActualNum(totalTypeBActualNum);

        sum.setTypeASaleAmount(totalTypeAAmount);
        sum.setTypeBSaleAmount(totalTypeBAmount);
        sum.setTypeB2SaleAmount(totalTypeB2Amount);

        sum.setTotalActualNum(totalTypeAActualNum + totalTypeBActualNum);
        sum.setTotalTargetNum(totalTypeATargetNum + totalTypeBTargetNum);
        sum.setTotalSaleAmount(totalStoreAmount);

        sum.setTypeACompleteRate(totalTypeANumRate);
        sum.setTypeBCompleteRate(totalTypeBNumRate);
        sum.setSaleNumCompleteRate(totalNumRate);
        sum.setSaleAmountActualRate(totalActualAmountRate);

        // 添加合计情况
        list.add(sum);
        return list;
    }

    /**
     * 
     * 功能描述: 计算综合完成率<br>
     *
     * @param typeANumRate
     * @param typeBNumRate
     * @return
     */
    private String calTotalNumRate(String typeANumRate, String typeBNumRate) {
        BigDecimal result = null;
        if (StringUtils.equals("--", typeANumRate) && StringUtils.equals("--", typeBNumRate)) {
            return "--";
        } else if (!StringUtils.equals("--", typeANumRate) && StringUtils.equals("--", typeBNumRate)) {
            result = new BigDecimal(typeANumRate).multiply(BigDecimal.valueOf(0.6));
        } else if (StringUtils.equals("--", typeANumRate) && !StringUtils.equals("--", typeBNumRate)) {
            result = new BigDecimal(typeBNumRate).multiply(BigDecimal.valueOf(0.4));
        } else {
            result = new BigDecimal(typeANumRate).multiply(BigDecimal.valueOf(0.6))
                    .add(new BigDecimal(typeBNumRate).multiply(BigDecimal.valueOf(0.4)));
        }

        if (result.compareTo(new BigDecimal(0)) == 0) {
            return "0.0%";
        } else {
            return BigDecimalUtils.getDigitPercent(String.valueOf(result));
        }
    }

    /**
     * 
     * 功能描述: 从实际销售列表中根据门店和任务类型取对应的那条记录<br>
     *
     * @param actualList
     * @param storeCode
     * @param taskType
     * @return
     */
    private StoreTaskTypeActualVo getActualByStoreAndType(List<StoreTaskTypeActualVo> actualList, String storeCode,
            String taskType) {
        if (CollectionUtils.isEmpty(actualList)) {
            return null;
        }

        for (StoreTaskTypeActualVo actual : actualList) {
            if (StringUtils.equals(actual.getStoreCode(), storeCode)
                    && StringUtils.equals(actual.getTaskType(), taskType)) {
                return actual;
            }
        }
        return null;
    }

    /**
     * 
     * 功能描述: 从门店品类总销售列表中根据门店编码取出对应的记录<br>
     *
     * @param totalList
     * @param storeCode
     * @return
     */
    private StoreTaskTotalAmountVo getTotalAmountByStore(List<StoreTaskTotalAmountVo> totalList, String storeCode) {
        if (CollectionUtils.isEmpty(totalList)) {
            return null;
        }

        for (StoreTaskTotalAmountVo total : totalList) {
            if (StringUtils.equals(total.getStoreCode(), storeCode)) {
                return total;
            }
        }
        return null;
    }

    // ============================================以上大区任务管理，以下大区分配=====================================================

    @Override
    public AreaTaskDetailVo queryAreaTaskDetailInfo(Long areaTaskId) {
        AreaTaskDetailVo areaTaskDetail = areaTaskDao.queryAreaTaskDetailByAreaTaskId(areaTaskId);
        areaTaskDetail.setTaskDate(buildTaskTime(areaTaskDetail.getTaskDate()));
        Integer totalTargetNum = areaTaskDao.queryAreaTaskTotalTargetNum(areaTaskId);
        Integer totalCompleteNum = areaTaskDao.queryAreaTaskTotalCompleteNum(areaTaskDetail.getHqTaskId(),
                areaTaskDetail.getDisCode());

        if (null == totalCompleteNum) {
            totalCompleteNum = 0;
        }
        areaTaskDetail.setTotalTargetNum(totalTargetNum);
        areaTaskDetail.setCompleteNum(totalCompleteNum);
        String completeRate = BigDecimalUtils.calPercent(totalCompleteNum, totalTargetNum);
        areaTaskDetail.setCompleteRate(completeRate);
        areaTaskDetail.setTargetRate(BigDecimalUtils.getDigitPercent(areaTaskDetail.getTargetRate()));
        return areaTaskDetail;
    }

    /**
     * 
     * 功能描述: yyyyMM格式修改为yyyy年MM月<br>
     * 
     * @param month
     * @return
     */
    private String buildTaskTime(String taskDate) {
        if (StringUtils.length(taskDate) != 6) {
            throw new SawpException("格式转换的入参长度不正确");
        }

        String year = StringUtils.substring(taskDate, 0, 4);
        String month = StringUtils.substring(taskDate, 4, 6);
        return year + "年" + month + "月";
    }

    @Override
    public QueryResult<AreaTaskModelDetailVo> queryAreaTaskModelDetail(Long areaTaskId, Integer pageNo,
            Integer pageLimit) {
        Integer pageSize = checkPageLimit(pageLimit);
        Integer startRow = (pageNo - 1) * pageSize;
        List<AreaTaskModelDetailVo> detailList = areaTaskDao.queryAreaTaskModelDetailList(areaTaskId, startRow,
                pageSize);
        AreaTask areaTask = areaTaskDao.queryAreaTaskByAreaTaskId(areaTaskId);

        // 加缓存
        List<AreaTaskModelCompleteVo> completeList = areaTaskDao.queryAreaTaskModelComplete(areaTask.getDisCode(),
                areaTask.getCateCode(), areaTask.getMonth());
        for (AreaTaskModelDetailVo detail : detailList) {
            detail.setCompleteNum(getAreaTaskModelCompleteVo(completeList, detail.getModelId()));
        }

        Integer totalSize = areaTaskDao.queryAreaTaskModelDetailSize(areaTaskId);
        QueryResult<AreaTaskModelDetailVo> result = new QueryResult<AreaTaskModelDetailVo>();
        result.setRecords(detailList);
        result.setTotalSize(totalSize);
        return result;
    }

    /**
     * 
     * 功能描述: 从大区款数完成情况中根据款数id取对应的值<br>
     *
     * @param completeList
     * @param modelId
     * @return
     */
    private Integer getAreaTaskModelCompleteVo(List<AreaTaskModelCompleteVo> completeList, Long modelId) {
        if (CollectionUtils.isEmpty(completeList)) {
            return 0;
        }
        for (AreaTaskModelCompleteVo model : completeList) {
            if (model.getModelId().longValue() == modelId.longValue()) {
                return model.getCompleteNum();
            }
        }
        return 0;
    }

    @Override
    public List<AreaTaskStoreDetailVo> queryAreaTaskDistributeDetail(Long areaTaskId, Long modelId) {
        List<AreaTaskStoreDetailVo> storeDetail = areaTaskDao
                .queryStoreTaskDistributeDetailByAreaTaskIdAndModelIdForAllStore(areaTaskId, modelId);
        return storeDetail;
    }

    @Override
    @Transactional
    public void modifyStoreTargetNum(Long areaTaskId, List<AreaTaskStoreDetailVo> storeModelModify, Boolean flag) {
        List<AreaTaskStoreDetailVo> insert = new ArrayList<AreaTaskStoreDetailVo>();
        List<AreaTaskStoreDetailVo> update = new ArrayList<AreaTaskStoreDetailVo>();
        AreaTask areaTask = areaTaskDao.queryAreaTaskByAreaTaskId(areaTaskId);
        if (flag) {
            Long modelId = storeModelModify.get(0).getModelId();
            // 前端页面传递的时候每次只有一个款数id
            List<AreaTaskStoreDetailVo> need2Del = checkModelDistributeNum(areaTaskId, modelId, storeModelModify);
            areaTaskDao.delNotNeedStoreModel(need2Del);

            List<AreaTaskStoreDetailVo> dbInfo = areaTaskDao
                    .queryStoreTaskDistributeDetailByAreaTaskIdAndModelId(areaTaskId, modelId);
            AreaTaskStoreDetailVo perDbInfo = null;

            @SuppressWarnings("unchecked")
            List<AreaTaskStoreDetailVo> last = ListUtils.removeAll(storeModelModify, need2Del);
            for (AreaTaskStoreDetailVo before : last) {
                perDbInfo = getTheSameStoreModel(dbInfo, before.getStoreTaskId(), before.getModelId());
                if (null == perDbInfo) {
                    insert.add(before);
                } else if (!before.getTargetNum().equals(perDbInfo.getTargetNum())) {
                    // before.getTargetNum()不会为null，perDbInfo.getTargetNum()可能为null
                    update.add(before);
                }
            }
            // 修改当前大区任务当前款数为分配完成
            areaTaskDao.modifyAreaModelRelStatus(areaTaskId, modelId,
                    MainPushConstants.AREA_TASK_MODEL_STATUS_DISTRIBUTED);
        } else {
            // 按款数操作
            Long modelId = null;
            List<AreaTaskStoreDetailVo> storeDetail = null;
            Map<Long, List<AreaTaskStoreDetailVo>> modelDistMap = getTheSameModel(storeModelModify);
            for (Map.Entry<Long, List<AreaTaskStoreDetailVo>> entry : modelDistMap.entrySet()) {
                modelId = entry.getKey();
                storeDetail = entry.getValue();

                List<AreaTaskStoreDetailVo> dbInfo = areaTaskDao
                        .queryStoreTaskDistributeDetailByAreaTaskIdAndModelId(areaTaskId, modelId);
                List<AreaTaskStoreDetailVo> need2Del = getExceptInImport(storeDetail, dbInfo);
                areaTaskDao.delNotNeedStoreModel(need2Del);

                AreaTaskStoreDetailVo perDbInfo = null;
                for (AreaTaskStoreDetailVo before : storeDetail) {
                    perDbInfo = getTheSameStoreModel(dbInfo, before.getStoreTaskId(), before.getModelId());
                    if (null == perDbInfo) {
                        insert.add(before);
                    } else {

                        // before.getTargetNum()不会为null，perDbInfo.getTargetNum()可能为null
                        if (!before.getTargetNum().equals(perDbInfo.getTargetNum())) {
                            update.add(before);
                        }
                    }
                }

                // 修改当前大区任务当前款数为分配完成
                areaTaskDao.modifyAreaModelRelStatus(areaTaskId, modelId,
                        MainPushConstants.AREA_TASK_MODEL_STATUS_DISTRIBUTED);
            }
        }

        if (!CollectionUtils.isEmpty(insert)) {
            areaTaskDao.batchSaveTaskModelNum(areaTask.getHqTaskId(), insert);
        }

        if (!CollectionUtils.isEmpty(update)) {
            areaTaskDao.updateStoreTaskModelNum(update);

            // 当前月记录小红点
            if (StringUtils.equals(areaTask.getMonth(), DateUtils.getThisMonth())) {
                // 记录小红点表
                List<RedPointTips> redPointTips = new ArrayList<RedPointTips>();
                RedPointTips tip = null;
                for (AreaTaskStoreDetailVo detail : update) {
                    tip = new RedPointTips();
                    tip.setModelId(detail.getModelId());
                    tip.setStoreCode(detail.getStoreCode());
                    tip.setChangeType(1);
                    tip.setCreateTime(new Date());
                    tip.setMonth(areaTask.getMonth());
                    redPointTips.add(tip);
                }
                redPointTipsService.saveRedPointTips(redPointTips);
            }
        }
        distributeStatusService.modifyAreaTaskStatus4DistriModelNum(areaTaskId);
        self.calAreaTaskAllStoreDistributeNum(areaTaskId);
    }

    @Override
    public void calAreaTaskAllStoreDistributeNum(Long areaTaskId) {
        // 拿到大区任务下属所有门店的总分配数量
        List<CalStoreTaskDistributeVo> calList = areaTaskDao.queryStoreTaskDistributeInfo(areaTaskId);
        // 更新入库
        areaTaskDao.calStoreTaskDistributeNum(calList);
    }

    /**
     * 
     * 功能描述: 求取数据库中存在，但是导入值中不存在的数据集，这部分数据需要删除<br>
     * 
     * @param importInfo
     * @param dbInfo
     * @return
     */
    private List<AreaTaskStoreDetailVo> getExceptInImport(List<AreaTaskStoreDetailVo> importInfo,
            List<AreaTaskStoreDetailVo> dbInfo) {

        List<AreaTaskStoreDetailVo> need2Del = new ArrayList<AreaTaskStoreDetailVo>();
        for (AreaTaskStoreDetailVo db : dbInfo) {
            Boolean flag = Boolean.FALSE;
            for (AreaTaskStoreDetailVo im : importInfo) {
                if (db.getStoreTaskId().longValue() == im.getStoreTaskId().longValue()) {
                    flag = Boolean.TRUE;
                }
            }

            if (!flag) {
                need2Del.add(db);
            }
        }
        return need2Del;
    }

    /**
     * 
     * 功能描述: 按款数统计下导入的分配list<br>
     * 
     * @param importInfo
     * @param modelId
     * @return
     */
    private Map<Long, List<AreaTaskStoreDetailVo>> getTheSameModel(List<AreaTaskStoreDetailVo> importInfo) {
        Map<Long, List<AreaTaskStoreDetailVo>> map = new HashMap<Long, List<AreaTaskStoreDetailVo>>();
        List<AreaTaskStoreDetailVo> theSameModel = null;
        for (AreaTaskStoreDetailVo detail : importInfo) {
            if (map.containsKey(detail.getModelId())) {
                theSameModel = map.get(detail.getModelId());
                theSameModel.add(detail);
            } else {
                theSameModel = new ArrayList<AreaTaskStoreDetailVo>();
                theSameModel.add(detail);
                map.put(detail.getModelId(), theSameModel);
            }
        }
        return map;
    }

    /**
     * 
     * 功能描述: 根据门店任务id和款数id，取db中的对应门店款数信息<br>
     * 
     * @param dbInfo
     * @param storeTaskId
     * @param modelId
     * @return
     */
    private AreaTaskStoreDetailVo getTheSameStoreModel(List<AreaTaskStoreDetailVo> dbInfo, Long storeTaskId,
            Long modelId) {
        if (CollectionUtils.isEmpty(dbInfo)) {
            return null;
        }
        for (AreaTaskStoreDetailVo store : dbInfo) {
            if (store.getStoreTaskId().longValue() == storeTaskId.longValue()
                    && store.getModelId().longValue() == modelId.longValue()) {
                return store;
            }
        }
        return null;
    }

    /**
     * 
     * 功能描述: 校验数量，并返回页面输入为空的门店任务id+款数id，表示要删除的<br>
     * 
     * @param areaTaskId
     * @param storeModelModify
     * @return
     */
    private List<AreaTaskStoreDetailVo> checkModelDistributeNum(Long areaTaskId, Long modelId,
            List<AreaTaskStoreDetailVo> storeModelModify) {

        List<AreaTaskStoreDetailVo> need2Del = new ArrayList<AreaTaskStoreDetailVo>();

        int totalNum = 0;
        for (AreaTaskStoreDetailVo detail : storeModelModify) {
            // -1表示删除的
            if (-1 != detail.getTargetNum().intValue()) {
                totalNum += detail.getTargetNum();
            } else {
                need2Del.add(detail);
            }
        }
        AreaModelRel areaModelRel = areaTaskDao.queryAreaModelRelById(areaTaskId, modelId);
        if (totalNum < areaModelRel.getTargetNum().intValue()) {
            throw new SawpException("分配数量小于目标总数量!");
        }

        return need2Del;
    }

    @Override
    public XSSFWorkbook exportAreaTaskInfo(Long areaTaskId) {
        AreaTask areaTask = areaTaskDao.queryAreaTaskByAreaTaskId(areaTaskId);
        List<AreaTaskTargetExportVo> areaTarget = areaTaskDao.queryAreaTaskModelDetail4Export(areaTaskId);
        List<StoreInfoVo> areaStore = areaTaskDao.queryStoreInfo(areaTaskId);

        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet(areaTask.getTaskTopic());

        // 第一行
        XSSFRow row = sheet.createRow(0);
        row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue("大区导出任务填写模板");

        // 第二行
        row = sheet.createRow(1);
        int column = 2;
        for (AreaTaskTargetExportVo target : areaTarget) {
            row.createCell(column++, Cell.CELL_TYPE_STRING).setCellValue(target.getModelName());
        }

        // 第三行
        row = sheet.createRow(2);
        row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue("门店编码");
        row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue("门店名称");
        column = 2;
        for (AreaTaskTargetExportVo target : areaTarget) {
            row.createCell(column++, Cell.CELL_TYPE_STRING).setCellValue(target.getCmmdtyCodes());
        }

        // 第四行
        row = sheet.createRow(3);
        row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue("合计目标");
        column = 2;
        for (AreaTaskTargetExportVo target : areaTarget) {
            row.createCell(column++, Cell.CELL_TYPE_STRING).setCellValue(target.getTargetNum());
        }

        // 第五行及后面的行，循环门店
        int rowNo = 4;
        for (StoreInfoVo store : areaStore) {
            row = sheet.createRow(rowNo++);
            row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue(store.getStoreCode());
            row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(store.getStoreName());
        }
        return wb;
    }

    @Override
    public void importAreaTaskDistribute(MultipartFile file, Long areaTaskId) {
        MainPushExcelHandle importExcel = new MainPushExcelHandle(file);
        Sheet sheetBook = importExcel.getSheetsFromWorkbook().get(0);
        List<List<String>> book = importExcel.getExcelContentFromSheet(sheetBook, 0, -1);
        LOG.info("导入excel元素详情:{}", book.toString());

        if (book.size() < 5) {
            throw new SawpException("请不要修改表格内容，表格至少有5行!");
        }

        // 表示每一行的内容
        List<String> row = null;

        // ======================>校验第一行内容，第一行只能占据第一列，list的Size只能为1，表示为标题，如还占据其他列，提醒，此行不参与运算
        row = book.get(0);
        if (row.size() != 1) {
            throw new SawpException("请确认第1行为标题信息!只能占据第1行第1列!");
        }

        // ======================>校验第二行内容，款数名称，其中第一列，第二列为空，因不参与运算，不能有内容
        row = book.get(1);

        if (row.size() <= 2) {
            throw new SawpException("第2行款数信息格式不正确!");
        }

        if (!StringUtils.isEmpty(row.get(0)) || !StringUtils.isEmpty(row.get(1))) {
            throw new SawpException("请确认第2行第1列、第2列应为空格!");
        }

        List<AreaTaskTargetExportVo> areaTarget = areaTaskDao.queryAreaTaskModelDetail4Export(areaTaskId);
        AreaTaskTargetExportVo target = null;

        List<AreaTaskTargetExportVo> modelInfo = new ArrayList<AreaTaskTargetExportVo>();
        AreaTaskTargetExportVo model = null;

        List<String> errorMsg = new ArrayList<String>();
        for (int i = 2; i < row.size(); i++) {
            target = getAreaTaskTargetExportVo(areaTarget, row.get(i));
            if (null == target) {
                errorMsg.add("第2行第" + (i + 1) + "列款数不存在!");
            } else {
                model = new AreaTaskTargetExportVo();
                model.setModelName(row.get(i));
                model.setModelId(target.getModelId());
                model.setCmmdtyCodes(target.getCmmdtyCodes());
                model.setTargetNum(target.getTargetNum());
                modelInfo.add(model);
            }
        }

        if (!CollectionUtils.isEmpty(errorMsg)) {
            throw new SawpException(errorStr(errorMsg));
        }

        // ======================>校验第三行内容，第三行校验格式，校验商品编码须和库中的一致
        row = book.get(2);
        if (row.size() != book.get(1).size()) {
            throw new SawpException("第3行的列数需和第2行一一对应!不能少也不能多!");
        }

        if (!StringUtils.equals(row.get(0), "门店编码")) {
            throw new SawpException("第3行第1列应为门店编码!");
        }

        if (!StringUtils.equals(row.get(1), "门店名称")) {
            throw new SawpException("3三行第2列应为门店名称!");
        }

        int cmmdtyI = 2;
        for (AreaTaskTargetExportVo cmmdtyPer : modelInfo) {
            if (!StringUtils.equals(cmmdtyPer.getCmmdtyCodes(), row.get(cmmdtyI))) {
                errorMsg.add("第3行第" + (cmmdtyI + 1) + "列商品信息错误!请不要修改导出的表格中的商品编码!");
            }
            cmmdtyI++;
        }

        if (!CollectionUtils.isEmpty(errorMsg)) {
            throw new SawpException(errorStr(errorMsg));
        }

        // ======================>校验第四行内容，第四行校验格式，校验款数数量
        row = book.get(3);
        if (row.size() != book.get(1).size()) {
            throw new SawpException("第4行的列数需和第2行款数一一对应!");
        }

        if (!StringUtils.isEmpty(row.get(0))) {
            throw new SawpException("第4行第1列应为空格!");
        }

        if (!StringUtils.equals(row.get(1), "合计目标")) {
            throw new SawpException("第4行第2列应为合计目标!");
        }

        int modelNumI = 2;
        Integer modelExcelNum = null;

        for (AreaTaskTargetExportVo modelPer : modelInfo) {
            Boolean flag = Boolean.TRUE;
            try {
                modelExcelNum = Integer.parseInt(row.get(modelNumI));
            } catch (Exception e) {
                LOG.error("导入大区分配任务,款数[{}]转化数量[{}]时发生异常:{}", modelPer.getModelName(), row.get(modelNumI),
                        e.getMessage(), e);
                errorMsg.add("第4行第" + (modelNumI + 1) + "列不是数字!");
                flag = Boolean.FALSE;
            }
            if (flag && modelPer.getTargetNum().intValue() != modelExcelNum.intValue()) {
                errorMsg.add("第4行第" + (modelNumI + 1) + "列数值和库中不相等，请不要修改表格中的合计目标数量!(重新下载模板)");
            }
            modelNumI++;
        }

        if (!CollectionUtils.isEmpty(errorMsg)) {
            throw new SawpException(errorStr(errorMsg));
        }

        // ======================>校验第五行及之后的内容
        List<StoreTask> storeTask = areaTaskDao.queryStoreTaskListByAreaTaskId(areaTaskId);
        StoreTask task = null;

        List<StoreInfoVo> areaStore = areaTaskDao.queryStoreInfo(areaTaskId);
        StoreInfoVo storeAc = null;

        List<AreaTaskStoreDetailVo> storeInfo = new ArrayList<AreaTaskStoreDetailVo>();
        AreaTaskStoreDetailVo store = null;

        Integer modelExcelDisNum = null;
        AreaTaskTargetExportVo targetExport = null;
        for (int i = 4; i < book.size(); i++) {
            row = book.get(i);

            if (row.size() > book.get(1).size()) {
                throw new SawpException("第" + (i + 1) + "行的列数需和第2行款数一一对应!");
            }

            storeAc = getStoreInfoVo(areaStore, row.get(0));
            if (null == storeAc) {
                throw new SawpException("第" + (i + 1) + "行门店编码"+row.get(0)+"不属于当前大区!");
            } else {
                int modelI = 0;
                for (int j = 2; j < row.size(); j++) {
                    Boolean flag = Boolean.TRUE;

                    if (StringUtils.isEmpty(row.get(j))) {
                        modelI++;
                        continue;
                    }

                    try {
                        modelExcelDisNum = Integer.parseInt(row.get(j));
                    } catch (Exception e) {
                        LOG.error("导入大区分配任务,转化门店[{},{}]分配数量[{}]时发生异常:{}", storeAc.getStoreCode(),
                                storeAc.getStoreName(), row.get(j), e.getMessage(), e);
                        flag = Boolean.FALSE;
                        errorMsg.add("第" + (i + 1) + "行第" + (j + 1) + "列不是数字!");
                    }
                    if (flag) {
                        store = new AreaTaskStoreDetailVo();
                        store.setStoreCode(storeAc.getStoreCode());
                        store.setStoreName(storeAc.getStoreName());
                        task = getStoreTask(storeTask, storeAc.getStoreCode());
                        store.setStoreTaskId(null != task ? task.getId() : null);

                        targetExport = modelInfo.get(modelI++);
                        store.setModelId(targetExport.getModelId());

                        // 把分配的数量加的每个款数下面，最后比较款数数量是否分配完毕
                        targetExport.setActualNum(targetExport.getActualNum() + modelExcelDisNum);
                        store.setTargetNum(modelExcelDisNum);
                        storeInfo.add(store);
                    }
                }
            }
        }

        if (!CollectionUtils.isEmpty(errorMsg)) {
            throw new SawpException(errorStr(errorMsg));
        }

        for (AreaTaskTargetExportVo info : modelInfo) {
            if (info.getActualNum() < info.getTargetNum()) {
                errorMsg.add(info.getModelName() + "分配数量小于目标数量，请确保目标数量被分配完毕!");
            }
        }

        if (!CollectionUtils.isEmpty(errorMsg)) {
            throw new SawpException(errorStr(errorMsg));
        }

        LOG.info(modelInfo.toString());
        LOG.info(storeInfo.toString());

        self.modifyStoreTargetNum(areaTaskId, storeInfo, false);
    }

    /**
     * 
     * 功能描述: 从门店任务数据中根据门店编码取出门店任务信息<br>
     *
     * @param storeTask
     * @param storeCode
     * @return
     */
    private StoreTask getStoreTask(List<StoreTask> storeTask, String storeCode) {
        for (StoreTask store : storeTask) {
            if (StringUtils.equals(store.getStoreCode(), storeCode)) {
                return store;
            }
        }
        return null;
    }

    /**
     * 
     * 功能描述: 从门店基础信息中根据门店编码取出门店信息<br>
     *
     * @param areaStore
     * @param storeCode
     * @return
     */
    private StoreInfoVo getStoreInfoVo(List<StoreInfoVo> areaStore, String storeCode) {
        for (StoreInfoVo store : areaStore) {
            if (StringUtils.equals(store.getStoreCode(), storeCode)) {
                return store;
            }
        }
        return null;
    }

    /**
     * 
     * 功能描述: 从导入的excel款数信息中根据款数名称取款数信息<br>
     *
     * @param areaTarget
     * @param modelName
     * @return
     */
    private AreaTaskTargetExportVo getAreaTaskTargetExportVo(List<AreaTaskTargetExportVo> areaTarget,
            String modelName) {
        for (AreaTaskTargetExportVo task : areaTarget) {
            if (StringUtils.equals(task.getModelName(), modelName)) {
                return task;
            }
        }
        return null;
    }

    /**
     * 
     * 功能描述: 从错误list的封装错误消息<br>
     *
     * @param errorMsg
     * @return
     */
    private String errorStr(List<String> errorMsg) {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        for (String msg : errorMsg) {
            sb.append(msg);
            if (++i < errorMsg.size()) {
                sb.append("\r\n");
            }
        }
        return sb.toString();
    }

    /**
     * 
     * 功能描述: page大小做必要的限制<br>
     *
     * @param pageLimit
     * @return
     */
    private Integer checkPageLimit(Integer pageLimit) {
        if (null == pageLimit || pageLimit <= 0) {
            return 10;
        } else if (pageLimit <= 100) {
            return pageLimit;
        } else {
            return 100;
        }

    }

}
